
import json
import re
import logging
logger = logging.getLogger("django")
from django import http
from django.contrib.auth import login, authenticate, logout
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from meiduo_mall.utils.view import LoginRequiredMixin
from users.models import User


class UsernameCountView(View):
    """判断用户是否为重复注册"""
    def get(self, request, username):

        try:
            count = User.objects.filter(username=username).count()
        except Exception as e:
            return JsonResponse({
                "code":400,
                "errmsg":"访问数据库失败"
            })
        return JsonResponse({
            "code": 200,
            "errmsg": "ok",
            "count": count
        })


class MobileCountView(View):
    def get(self, request,mobile):
        """判断手机号码是否重复注册"""

        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return JsonResponse({
                "code": 400,
                "errmsg": "访问数据库失败"
            })
        return JsonResponse({
            "code": 200,
            "errmsg": "ok",
            "count": count
        })


class RegisterView(View):

    def post(self, request):
        '''接收参数, 保存到数据库'''
        # 1.接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        password2 = dict.get('password2')
        mobile = dict.get('mobile')
        allow = dict.get('allow')
        sms_code_client = dict.get('sms_code')

        # 2.校验(整体)
        if not all([username, password, password2, mobile, allow, sms_code_client]):
            return http.JsonResponse({'code':400,
                                      'errmsg':'缺少必传参数'})

        # 3.username检验
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.JsonResponse({'code': 400,
                                      'errmsg': 'username格式有误'})

        # 4.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({'code': 400,
                                      'errmsg': 'password格式有误'})

        # 5.password2 和 password
        if password != password2:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '两次输入不对'})
        # 6.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'code': 400,
                                      'errmsg': 'mobile格式有误'})
        # 7.allow检验
        if allow != True:
            return http.JsonResponse({'code': 400,
                                      'errmsg': 'allow格式有误'})

        # 8.sms_code检验 (链接redis数据库)
        redis_conn = get_redis_connection('verify_code')

        # 9.从redis中取值
        sms_code_server = redis_conn.get('sms_%s' % mobile)

        # 10.判断该值是否存在
        if not sms_code_server:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '短信验证码已过期'})
        # 11.把redis中取得值和前端发的值对比
        if sms_code_client != sms_code_server.decode():
            return http.JsonResponse({'code': 400,
                                      'errmsg': '验证码不正确'})

        # 12.保存到数据库 (username password mobile)
        try:
            user = User.objects.create_user(username=username,
                                            password=password,
                                            mobile=mobile)
        except Exception as e:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '保存到数据库出错'})
        # 实现状态保持
        login(request, user)

        # 13.拼接json返回
        respone = JsonResponse({'code': 0,
                         'errmsg': 'ok'})
        respone.set_cookie('usename',
                           user.username,
                           max_age=3600 * 24 *7)
        return respone


class LoginView(View):
    def post(self, request):
        """实现登录接口"""

        # 接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        remembered = dict.get('remembered')

        # 整体校验参数
        if not all([username, password]):
            return http.JsonResponse({
                "code": 400,
                "errmsg": "缺少必要参数"
            })
        user = authenticate(username=username,password=password)
        if not user:
            return JsonResponse({"code": 400, "errmsg": "用户名或密码错误"})

        # 状态保持
        login(request,user)

        # 判断是否记住用户
        if remembered != True:
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)
        response = JsonResponse({
            "code":0,
            "errmsg":"ok"
        })
        response.set_cookie('username', user.username, max_age=3600 * 24 * 7)
        return response


class LogoutView(View):
    def delete(self, request):
        """实现退出登录"""

        # 清理session
        logout(request)

        # 创建response对象

        response = JsonResponse({
            "code": 0,
            "errmsg": "ok"
        })
        # 调用对象的delete_cookie 方法 清除cookie
        response.delete_cookie("username")

        return response


class UserInfoView(LoginRequiredMixin, View):
    """用户中心"""
    def get(self,request):
        """提供个人信息界面"""

        info_data = {
            "username":request.user.username,
            "mobile":request.user.mobile,
            "email":request.user.email,
            "email_active":request.user.email_active
        }
        return JsonResponse({
            "code": 0,
            "errmsg": 'ok',
            "info_data": info_data
        })


class EmailView(View):
    """添加邮箱"""

    def put(self, request):
        """实现添加邮箱逻辑"""
        # 接收参数
        json_dict = json.loads(request.body.decode())
        email = json_dict.get("email")
        # 校验参数
        if not email:
            return JsonResponse({
                "code": 400,
                "errmsg": '缺少email参数'
            })
        try:
            # 赋值email字段
            request.user.email = email
            # 保存
            request.user.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({
                "code": 400,
                "errmsg": "添加邮箱失败"
            })
        # 变换 email 的格式: 从 '123456@qq.com' 变为: '<123456@qq.com>'
        email = "<"+ email + ">"
        # 从 celery_tasks 中导入:
        from celery_tasks.email.tasks import send_verify_email
        # 调用发送函数
        verify_url = request.user.generate_verify_email_url()
        send_verify_email.dalay(email, verify_url)
        # 响应结果

        return JsonResponse({
            "code": 0,
            "errmsg": "ok"
        })


class VerifyEmailView(View):
    """验证邮箱"""

    def put(self,request):
        """实现邮箱验证逻辑"""
        # 接收参数
        token = request.GET.get("token")
        # 校验参数
        if not token:
            return JsonResponse({
                "code": 400,
                "errmsg": "缺少token"
            })
        # 调用封装好的方法，将token传入
        user = User.check_verify_email_token(token)
        if not user:
            return JsonResponse({
                "code": 400,
                "errmsg": "无效token"
            })
        # 修改email_active的值为True
        try:
            user.email_active = True
            user.seve()
        except Exception as e:
            logger.error(e)
            return JsonResponse({
                "code": 400,
                "errmsg": "激活失败"
            })
        # 返回邮箱验证结果
        return JsonResponse({
            "code": 0,
            "errmsg": "ok"
        })
























